简化循环和逻辑
一、流程控制
1. 判断
1)条件判断中的参数顺序
比较的左侧 | 比较的右侧 |
---|---|
“被问询的”表达式,更倾向于不断变化 | 用来做比较的表达式,它的值更倾向于常量 |
PS:但是反着写,能够避免掉那种if(obj = NULL)
的错误,俗称“尤达表示法”。
2)if/else 语句块的顺序
三个倾向性:
- 倾向于先处理正逻辑,再处理负逻辑
- 倾向于先处理掉简单情况
- 倾向于先处理掉有趣的或者可疑的状况
3)?:条件表达式
- 并不是很推荐这种写法哈哈哈哈,一旦写了长表达式,就会很难理解
2. 循环
1)避免使用 do/while 循环
通常,逻辑条件应该出现在它们所“保护”的代码前。而且do/while
循环中的continue
会产生歧义。
2)最小化嵌套
深嵌套会让读者的“思维栈”太深,可以通过提早返回来减少嵌套,可以将代码进行如下变化:
1 | if (a) { |
1 | if (!a) { |
二、长表达式拆分
方法一:增加变量:总结为一句话,用额外的变量,来代替一个长表达式,例子:
1
2
3
4
5
6
7
8
9
10
11// 解释变量
if (line.split(":")[0].strip() == "root") {
// ...
}
// **************************************
// ↓
// **************************************
var userName = line.split(":")[0].strip();
if (username == "root") {
// ...
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// 总结变量
if (request.user.id == document.owner_id) {
// ...
}
// ...
if (request.user.id != document.owner_id) {
// ...
}
// ***********************************************************
// ↓
// ************************************************************
var user_owns_document = request.user.id == document.owner_id;
if (user_owns_document) {
// ...
}
if (!user_owns_document) {
// ...
}方法二:使用德摩根定律
- !(a || b || c) <=> (!a) && (!b) && (!c)
- !(a && b && c) <=> (!a) || (!b) || (!c)
方法三:不要滥用短路逻辑:短路逻辑可能会增加代码的理解难度。
方法四:找到更优雅的方式,一个理念是:
开始还很简单的问题变得非常令人费解,通常预示着一中更简单的方法。
方法五:拆分巨大的语句,把一样的表达式抽离出来作为函数开头的总结变量
- DRY:Don’t Repeat Yourself.
三、变量
关于变量的三个问题:
- 变量越多,就越难全部追踪
- 变量作用域越大,就需要跟踪的越久
- 变量改变越频繁,就越难追踪它的当前值
1)减少变量
针对第一个问题,我们提出了以下几种方案,可以去掉以下几种不必要的变量:
没有价值的临时变量:举个例子:
now = datetime.datetime.now()
,一般这种变量有以下几种特点,- 没有拆分任何临时变量
- 没有做过多澄清,
datetime.now()
已经足够清晰 - 只用一次(或少数几次),没有压缩任何冗余的代码
中间结果:下面例子中,
index_to_remove
可以被移除,那些为了保存临时结果,用完即丢的变量,可以考虑丢弃:
1 | var remove_one = function (array, value_to_remove) { |
- 流程控制变量:用来控制流程的变量,往往不包含任何程序内的数据,能通过结构化编程来消除。
2)缩小变量作用域
让你的变量对尽量少的代码行可见。
一个做法就是让变量“降级”,尽量降低作用域,比如
- 让类成员变量降级成某个成员函数中的局部变量
- 运用好
C++
的块级作用域,那些仅仅用来当做判断条件的变量,可以放在if
语句中定义:
1
2
3
4
5
6
7
8
9
10PaymentInfo* info = database.ReadPaymentInfo()
if(info){
// ...
}
// ************************************************
// ↓
// ************************************************
if(PaymentInfo* info = database.ReadPaymentInfo()){
// ...
}- 用
JavaScript
的立即执行函数制造封闭的作用域
定义下移:将定义移动到使用它之前,增加可读性
3)只写一次的变量更好
尽量减少对变量的赋值的语句,有助于提高可读性。